package org.zn.mvcbase.mybatis;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import javax.persistence.Column;

import org.zn.commons.reflection.ObjectInvoker;

import com.google.common.collect.Lists;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

public class ExampleProvider {
	
	private ObjectInvoker objectInvoker;
	
	private Object entity;
	
	private List<String> orders;
	
	private ExampleProvider(Object entity) {
		
		this.entity=entity;
		this.objectInvoker=ObjectInvoker.wrapper(entity);
	}
	
	public static ExampleProvider wrapperEntity(Object entity) {
		 
		ExampleProvider ep=new ExampleProvider(entity);
		
		return ep;
		
	}
	
	
	
	private  ExampleProvider addOrder(String	property) {
		 
		if(orders==null)orders=Lists.newArrayList();
		orders.add(property);
		
		return this;
		
	}
	
	private void setOrder() {
	
	}
	
	
	

	public Example provider() {

		Class clazz = entity.getClass();

		Field[] fids = clazz.getDeclaredFields();

		Example ex = new Example(clazz);

		for (Field field : fids) {

			Examplee[] exps = field.getAnnotationsByType(Examplee.class);

			if(exps==null) continue;
			
			Examplee[] exee=exps;//exps.value();
			
			
			for (Examplee examplee : exee) {
				
				if (exps != null) {

					doExamples(ex, field, examplee, entity);

				}
			}

		}

		return ex;

	}

	public Example provider(String group)  {

		Class clazz = entity.getClass();

		Field[] fids = clazz.getDeclaredFields();

		Example ex = new Example(clazz);

		for (Field field : fids) {

			Examples exps = field.getAnnotation(Examples.class);

			Examplee[] exee=exps.value();
			
			for (Examplee examplee : exee) {
				
				if (exps != null && group.equals(examplee.group())) {

					doExamples(ex, field, examplee, entity);

				}
			}
			
		}

		return ex;

	}

	private void doExamples(Example ex, Field field, Examplee expee, Object entity) {

		Column col = field.getAnnotation(Column.class);

		String colname = field.getName();

		if (col != null)
			colname = col.name();

		String condition = expee.condition();

		String relation = expee.relation();
		
		String suffix=	expee.suffix();
		String prefix=	expee.prefix();

		Object value=null;
		try {
			value = objectInvoker.InvokeMethod(ObjectInvoker.getterName(field.getName()), null);
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if(value==null) return;
		
		
		
		value= prefix!=null?prefix+value:value;
		value= suffix!=null?value+suffix:value;
		
		
		Criteria ca = ex.createCriteria();
		
		if (relation.equals("and")) {

			ca.andCondition(colname + " " + condition , value);
			ex.and(ca);

		} else if (relation.equals("or")) {

			ca.orCondition(colname + " " + condition , value);

			ex.or(ca);

		}

	}

}
